package com.biz.primus.ms.order.service.bulider;

import com.biz.primus.base.exception.BizSilentException;
import com.biz.primus.base.exception.utils.AssertUtils;
import com.biz.primus.model.oms.enums.OrderPaymentState;
import com.biz.primus.model.order.enums.OrderState;
import com.biz.primus.model.order.enums.PaymentState;
import com.biz.primus.model.order.exception.OrderException;
import com.biz.primus.model.order.exception.utils.AssertRequestParameter;
import com.biz.primus.ms.order.dao.po.Order;
import com.biz.primus.ms.order.service.helper.OrderServiceHelper;
import com.biz.primus.ms.order.service.helper.OrderStateStreamHelper;

/**
 * 取消订单构建器
 *
 * @author Tiger Feng
 * @date 2017年11月18日
 */
public class CancelOrderBuilder {
    private Order order;
    /**
     * 订单服务助手，构造方法注入
     */
    private OrderServiceHelper serviceHelper;
    private OrderStateStreamHelper stateStreamHelper;

    public CancelOrderBuilder(Order order,
                              OrderServiceHelper serviceHelper,
                              OrderStateStreamHelper stateStreamHelper) {
        this.order = order;
        this.serviceHelper = serviceHelper;
        this.stateStreamHelper = stateStreamHelper;
    }

    /**
     * 1、创建构建器
     *
     * @param order             订单
     * @param serviceHelper     订单服务助手
     * @param stateStreamHelper 订单状态助手
     * @return
     */
    public static CancelOrderBuilder newBuilder(Order order,
                                                OrderServiceHelper serviceHelper,
                                                OrderStateStreamHelper stateStreamHelper) {
        AssertRequestParameter.notNull(order, "订单不存在");
        AssertUtils.notNull(serviceHelper, OrderException.ORDER_HELPER_CAN_NOT_NULL);
        return new CancelOrderBuilder(order, serviceHelper, stateStreamHelper);
    }

    /**
     * 2、前置检查
     *
     * @return
     */
    public CancelOrderBuilder check() {
        switch (order.getState()) {
            case WAIT_SEND:
                if (order.getPaymentState() != PaymentState.PAY_ON_DELIVERY){
                    throw new BizSilentException(OrderException.CANNOT_CANCEL_PAID_ORDER);
                }
                break;
            default:
                break;
        }
        return this;
    }

    /**
     * 3、执行取消
     *
     * @return
     */
    public CancelOrderBuilder cancel() {
        // 支付完成的订单不能取消，只能"申请退款"
        // 货到付款 > 已出库：不能取消
        //         > 未出库：取消，并通知OMS
        // 未支付 > 直接取消
        //       是否已经使用优惠券，

        // WAIT_PAY(-1, "待付款"),
        // WAIT_SEND(0, "待发货"),
        // WAIT_RECEIVE(5, "待收货"),
        // WAIT_EVALUATION(10, "待评价"),
        // FINISHED(20, "订单完成"),
        // CANCELED(30,"取消"),
        // AFTER_SALE(50, "售后中"),
        // FINISHED_AFTER_SALE(55, "售后完成"),

        switch (order.getPaymentState()) {
            // 待支付
            case WAIT_PAY:
                order.setState(OrderState.CANCELED);
                serviceHelper.saveOrder(order);
                break;
            // 货到付款
            case PAY_ON_DELIVERY:
                switch (order.getDelivery().getDeliveryState()) {
                    // 待出库
                    case FOR_OUTBOUND:
                        order.setState(OrderState.CANCELED);
                        serviceHelper.saveOrder(order);

                        try {
                            // 通知OMS，接口调用方式，如果已打单，则无法取消
                            stateStreamHelper.sendUserCancelOrder(order);
                        } catch (Exception e) {
                            e.printStackTrace();
                            throw new BizSilentException(OrderException.CANCEL_PAY_ON_DELIVERY_FAILED);
                        }
                        break;
                    // 待自提、配送中、已签收、部分签收、拒收
                    default:
                        throw new BizSilentException(OrderException.CANNOT_CANCEL_EX_STOCK_ORDER);
                }
                break;
            // 支付失败
            case PAY_FAILURE:
                order.setState(OrderState.CANCELED);
                serviceHelper.saveOrder(order);
                break;
            // 已支付
            case PAY_SUCCESS:
                throw new BizSilentException(OrderException.CANNOT_CANCEL_PAID_ORDER);
            default:
                throw new BizSilentException(OrderException.NO_SUPPORT_PAYMENT_STATE);
        }
        return this;
    }
}
